
const findType = (o) => {
    return Object.prototype.toString.call(o)
}

const vNormal = (o, p = '') => {
    return `<span class="font-Monaco">${o}</span>${p}`
}

const vNormalKey = (o, p = '') => {
    return `<span class="normal-key font-Monaco">${o}</span>${p}`
}

const arrIndex = (o) => {
    let t = `
    <span class="array-index font-Monaco">${o}</span>:&nbsp;
    <span class="array-index-right"></span>
    `
    return t
}

const vString = (str) => {
    return `<span class="string-color font-Monaco">${str}</span>`
}

const vNumBool = (o) => {
    return `<span class="number-color font-Monaco">${o}</span>`
}

const protoLen = (o) => {
    return `<span class="proto-len font-Monaco">${o}</span>&nbsp;`
}

const randerObject = (obj) => {
    const alen = Object.keys(obj).length
    let t = `<div class="more-line">`
    t += `<div class="head-line">`
    t += `<i class="iconfont icon-you symbol-icon">&nbsp;&nbsp;</i>`
    t += `<span class="botm-10 new-line font-Monaco">`

    t += `(${alen})`

    t += ` { `
    let zk = ``

    const keys = Object.keys(obj)
    for (let i = 0; i < keys.length; i++) {
        const k = keys[i]
        const v = obj[k]
        const visitType = findType(v)
        if (visitType === '[object Object]') {
            // const objVal = randerObject(v)
            let vlen = Object.keys(v).length
            let key = vNormalKey(k, '')
            //
            t += key + ':&nbsp;'
            t += vNormal(`{...},&nbsp;`)
            //
            let value = ''
            if (vlen > 0) {
                value = randerObject(v)
            } else {
                value = vNormal(`{ }`)
            }
            zk += `<span class="one-line">` + arrIndex(k)
            zk += `<span class="wtd-90">` + value + `</span>`
            zk += `</span>`
            //
        } else if (visitType === '[object Array]') {
            //
            let key = vNormalKey(k, '')
            let alen = v.length
            //
            t += key + ':&nbsp;'
            t += vNormal(`Array(${alen})`)
            //
            let value = ''
            if (alen > 0) {
                value = randerArray(v)
            } else {
                value = vNormal(`[ ]`)
            }
            zk += `<span class="one-line">` + arrIndex(k)
            zk += `<span class="wtd-90">` + value + `</span>`
            zk += `</span>`
            //
        } else if (visitType === '[object Number]') {
            //
            let key = vNormalKey(k, '')
            let value = vNumBool(v)
            //
            t += key + ':&nbsp;&nbsp;'
            t += value + ',&nbsp;&nbsp;'
            //
            zk += `<span class="one-line">` + arrIndex(k)
            zk += `<span class="wtd-90">` + value + `</span>`
            zk += `</span>`
            //
        } else if (visitType === '[object String]') {
            //
            let key = arrIndex(k)
            let value = vString(`"${v}"`)
            //
            t += key
            t += value + `,&nbsp;`
            //
            zk += `<span class="one-line">` + arrIndex(k)
            zk += `<span class="wtd-90">` + value + `</span>`
            zk += `</span>`
            //
        } else if (visitType === '[object Boolean]') {
            //
            let key = arrIndex(k)
            let value = vNumBool(v)
            //
            t += key + ':&nbsp;&nbsp;'
            t += value
            //
            zk += `<span class="one-line">` + arrIndex(k)
            zk += `<span class="wtd-90">` + value + `</span>`
            zk += `</span>`
            //
        }
    }

    t += '}'

    t += `</span>`
    t += `</div>`
    t += objectZk(zk)
    t += `</div>`

    return t
}

const randerArray = (arr) => {
    const alen = arr.length
    let t = `<div class="more-line">`
    t += `<div class="head-line">`
    t += `<i class="iconfont icon-you symbol-icon">&nbsp;&nbsp;</i>`
    t += `<span class="botm-10 new-line font-Monaco">`

    t += `(${alen})`

    t += ` [ `
    let zk = ``
    for (let i = 0; i < arr.length; i++) {
        const e = arr[i]
        const visitType = findType(e)
        if (visitType === '[object Object]') {
            // const objVal = randerObject(e)
            //
            // t += vNormal(objVal)
            t += vNormal('{...},&nbsp;')
            //
            zk += `<span class="one-line">` + arrIndex(i)
            zk += `<span class="wtd-90">` + randerObject(e) + `</span>`
            zk += `</span>`

            //
        } else if (visitType === '[object Array]') {
            let elen = e.length
            //
            t += vNormal(`Array(${elen}),&nbsp;`)
            //
            zk += `<span class="one-line">` + arrIndex(i)
            zk += `<span class="wtd-90">` + randerArray(e) + `</span>`
            zk += `</span>`
            //
        } else if (visitType === '[object Number]') {
            //
            let num = vNumBool(e)
            t += num + ',&nbsp;'
            //
            zk += `<span class="one-line">` + arrIndex(i)
            zk += `<span class="wtd-90">` + num + `</span>`
            zk += `</span>`
            //
        } else if (visitType === '[object String]') {
            //
            t += vString(`"${e}"`) + `,&nbsp;`
            //
        } else if (visitType === '[object Boolean]') {
            //
            let bo = vNumBool(e)
            t += bo
            //
            zk += `<span class="one-line">` + arrIndex(i)
            zk += `<span class="wtd-90">` + bo + `</span>`
            zk += `</span>`
            //
        }
        // if (i > 2) {
        //     t += '...'
        //     break
        // }
    }
    // t = t.slice(0, t.length - 7)
    t += `] `

    t += `</span>`
    t += `</div>`
    t += arrayZk(zk, alen)
    t += `</div>`
    return t
}

const OAGeneral = () => {

}

const arrayZk = (str, alen) => {
    let zk = `<div class="left-30 vlog-show hide-log">`
    zk += str
    zk += protoLen('__length_') + `:&nbsp;${alen}<br>`
    zk += protoLen('__proto__') + ':&nbsp;' + 'Array(0)'
    zk += `</div>`
    return zk
}

const objectZk = (str) => {
    let zk = `<div class="left-30 vlog-show hide-log">`
    zk += str
    zk += protoLen('__proto__') + ':&nbsp;' + 'Object'
    zk += `</div>`
    return zk
}

const mlog = (...args) => {
    // 如果想在 console 里面查看结果
    console.log(...args)

    let t = ''
    for (let i = 0; i < args.length; i++) {
        let e = args[i]
        // console.log(typeof e)
        if (isObject(e)) {
            // 对象
            // let s = JSON.stringify(e, null, 2)
            // let s = json(e)
            let r = randerObject(e)
            // {}
            // t += '<hr>'

            // t += `<div class="border1">Object:<pre>`
            t += `<div class="border1">`
            t += `<div class="head-title"><span class="title-left">Object:</span>`
            t += `<span class="title-right">`
            t += `<div class="cls-btn-zk" onClick="foldAll(this)">展开全部</div>`
            t += `</span></div>`

            t += `<pre>`

            t += `${r}`
            t += `</pre></div>`
            //
        } else if (isArray(e)) {
            // 数组, 遍历里面的元素
            const r = randerArray(e)
            // []
            // t += '<hr>'

            // t += `<div class="border1">Array:<pre>`
            t += `<div class="border1">`
            t += `
            <div class="head-title">
            <span class="title-left">Array:</span>`
            t += `<span class="title-right">`
            t += `<div class="cls-btn-zk" onClick="foldAll(this)">展开全部</div>`
            t += `</span></div>`

            t += `<pre>`

            t += `${r}`
            t += `</pre></div>`
            //
        } else {
            // console.log(66, '普通类型', typeof e)
            if (typeof e === 'number' || typeof e === 'boolean') {
                // console.log(68, e, 'number')
                let nbo = vNumBool(e)
                t += `${nbo},&nbsp;&nbsp;`
            } else if (typeof e === 'string') {
                // console.log(70, e, 'string')
                let str = vString(`"${e}"`)
                t += `${str},&nbsp;&nbsp;`
            } else {
                t += vNormalKey(e, '') + `,&nbsp;&nbsp;`
            }
        }
    }
    t += '<hr>'
    let result = e('#console-log')
    result.innerHTML += t
    //
}

const handleFold = () => {
    const logDiv = e('#console-log')
    logDiv.addEventListener('click', event => {
        const target = event.target
        //
        const grandFather = target.parentNode.parentNode
        // 点击 icon 图标, 如果图标存在
        const icon = grandFather.querySelector('.symbol-icon')
        if (icon) {
            toggleIcon(target)

            const left30 = grandFather.querySelector('.left-30')
            toggleLog(left30)
        }
    })
}

const toggleIcon = (icon) => {
    if (icon.classList.contains('icon-you')) {
        // 展开
        toggleIconOpen(icon)
        // icon.classList.remove('icon-you')
        // icon.classList.add('icon-xia')
    } else if (icon.classList.contains('icon-xia')) {
        // 折叠
        toggleIconClose(icon)
        // icon.classList.remove('icon-xia')
        // icon.classList.add('icon-you')
    }
}

const toggleIconOpen = (ele) => {
    // 图标向下
    ele.classList.remove('icon-you')
    ele.classList.add('icon-xia')
}

const toggleIconClose = (ele) => {
    // 图标向右
    ele.classList.remove('icon-xia')
    ele.classList.add('icon-you')
}

const toggleLog = (ele) => {
    // console.log(1)
    if (ele.classList.contains('hide-log')) {
        // console.log(2)
        // 如果有 remoe
        ele.classList.remove('hide-log')
    } else {
        // console.log(3)
        // 没有 add
        ele.classList.add('hide-log')
    }
}

const foldAll = (obj) => {
    // 当前节点 obj
    const map = {
        open: '展开全部',
        fold: '折叠全部',
    }

    // const divlog = e('#console-log')
    // let a = divlog.querySelectorAll('.cls-btn-zk')
    let b = obj.parentNode.parentNode.parentNode
    let pre = b.querySelector('pre')
    // mlog(497, pre)
    //
    let f_name = obj.innerHTML
    if (f_name === '展开全部') {
        obj.innerHTML = map['fold']
        // 展开
        toggleDigvOpen(pre)
    } else if (f_name === '折叠全部') {
        obj.innerHTML = map['open']
        // 折叠
        toggleDigvFold(pre)
    }
    // 递归 展开 或 折叠
    // toggleDigv(pre)
}

const toggleDigv = (ele) => {
    let icon = ele.querySelector('.symbol-icon')
    // 删除 icon-you 添加 icon-xia
    icon.classList.toggle('icon-you')
    icon.classList.toggle('icon-xia')

    // remove hide-log
    let leftEle = ele.querySelector('.left-30')
    leftEle.classList.toggle('hide-log')

    // 获取子节点
    let lft = leftEle.childNodes
    if (!leftEle || !lft) {
        return
    }

    for (let i = 0; i < lft.length; i++) {
        const item = lft[i]
        // 找到所有的 one-line
        if (item.classList && item.classList.contains('one-line')) {
            let child = item.querySelector('.left-30')
            //
            if (child) {
                toggleDigv(item)
            }
        }
    }
}

const toggleDigvOpen = (ele) => {
    // open 展开, 去掉 hide-log icon-xia
    let icon = ele.querySelector('.symbol-icon')

    // 删除 icon-you 添加 icon-xia
    icon.classList.remove('icon-you')
    icon.classList.add('icon-xia')

    // remove hide-log
    let leftEle = ele.querySelector('.left-30')
    leftEle.classList.remove('hide-log')

    // 获取子节点
    let lft = leftEle.childNodes
    if (!leftEle || !lft) {
        return
    }

    for (let i = 0; i < lft.length; i++) {
        const item = lft[i]
        // 找到所有的 one-line
        if (item.classList && item.classList.contains('one-line')) {
            let child = item.querySelector('.left-30')
            //
            if (child) {
                toggleDigvOpen(item)
            }
        }
    }
}

const toggleDigvFold = (ele) => {
    // open 展开, 去掉 hide-log icon-xia
    let icon = ele.querySelector('.symbol-icon')

    // 删除 icon-xia 添加 icon-you
    icon.classList.remove('icon-xia')
    icon.classList.add('icon-you')

    // remove hide-log
    let leftEle = ele.querySelector('.left-30')
    leftEle.classList.add('hide-log')

    // 获取子节点
    let lft = leftEle.childNodes
    if (!leftEle || !lft) {
        return
    }

    for (let i = 0; i < lft.length; i++) {
        const item = lft[i]
        // 找到所有的 one-line
        if (item.classList && item.classList.contains('one-line')) {
            let child = item.querySelector('.left-30')
            //
            if (child) {
                toggleDigvFold(item)
            }
        }
    }
}

// kuai
const renderConsoleLog = function() {
    // log kuai_tool
    showCurrentElement('#console-log')
}

